package com.question.business.org.service.impl;

import com.alibaba.excel.EasyExcelFactory;
import com.alibaba.excel.ExcelWriter;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.question.business.org.entity.Org;
import com.question.business.org.mapper.OrgMapper;
import com.question.business.org.model.ao.*;
import com.question.business.org.model.vo.*;
import com.question.business.org.service.IOrgDeptService;
import com.question.business.org.service.IOrgService;
import com.question.business.user.service.IUserOrgService;
import com.question.common.constants.NumberConstants;
import com.question.common.constants.StringConstants;
import com.question.common.exception.BusinessException;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.ServletOutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * 机构服务实现类
 *
 * @author star
 * @since 2023-09-14
 */
@Slf4j
@Service
@AllArgsConstructor
public class OrgServiceImpl extends ServiceImpl<OrgMapper, Org> implements IOrgService {

    private final IOrgDeptService orgDeptService;

    private final IUserOrgService userOrgService;

    /**
     * 机构分页查询
     *
     * @param ao 请求参数
     * @return Page<OrgVO> 响应参数
     */
    @Override
    public Page<OrgVO> queryOrgPage(OrgPageAO ao) {
        return baseMapper.queryOrgPage(ao.createPage(), ao);
    }

    /**
     * 机构明细查询
     *
     * @param id 机构ID
     * @return OrgDetailVO 响应参数
     */
    @Override
    public OrgDetailVO queryOrgDetail(String id) {
        Org entity = super.getById(id);
        if (Objects.nonNull(entity)) {
            OrgDetailVO vo = new OrgDetailVO();
            BeanUtils.copyProperties(entity, vo);
            if (StringConstants.PARENT_ID.equals(vo.getParentId())) {
                vo.setParentId(null);
            } else {
                Org org = baseMapper.selectById(vo.getParentId());
                vo.setParentName(Objects.nonNull(org) ? org.getOrgName() : null);
            }
            vo.setDeptIds(orgDeptService.queryDeptByOrgId(vo.getId()));
            vo.setUserIds(userOrgService.queryUserByOrgId(vo.getId()));
            return vo;
        }
        return null;
    }

    /**
     * 机构新增数据
     *
     * @param ao 请求参数
     * @return OrgAddVO 响应参数
     */
    @Override
    public OrgAddVO addOrg(OrgAddAO ao) {
        Org entity = new Org();
        BeanUtils.copyProperties(ao, entity);
        if (StringUtils.isBlank(entity.getParentId())) {
            entity.setParentId(StringConstants.PARENT_ID);
        }
        super.save(entity);
        orgDeptService.addOrgDept(entity.getId(), ao.getDeptIds());
        userOrgService.addOrgUser(entity.getId(), ao.getUserIds());
        OrgAddVO vo = new OrgAddVO();
        vo.setId(entity.getId());
        return vo;
    }

    /**
     * 机构修改数据
     *
     * @param ao 数据
     */
    @Override
    public void updateOrg(OrgUpdateAO ao) {
        Org entity = new Org();
        BeanUtils.copyProperties(ao, entity);
        if (StringUtils.isBlank(entity.getParentId())) {
            entity.setParentId(StringConstants.PARENT_ID);
        } else if (ao.getParentId().equals(entity.getId())) {
            throw new BusinessException("上级机构不能选自己");
        }
        orgDeptService.addOrgDept(entity.getId(), ao.getDeptIds());
        userOrgService.addOrgUser(entity.getId(), ao.getUserIds());
        super.updateById(entity);
    }

    /**
     * 机构删除数据
     *
     * @param id 机构ID
     */
    @Override
    public void deleteOrg(String id) {
        super.removeById(id);
        orgDeptService.addOrgDept(id, null);
        userOrgService.addOrgUser(id, null);
    }

    /**
     * 机构批量删除数据
     *
     * @param ids 机构ID
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void deleteBatchOrg(List<String> ids) {
        super.removeBatchByIds(ids);
        for (String id : ids) {
            orgDeptService.addOrgDept(id, null);
            userOrgService.addOrgUser(id, null);
        }
    }

    /**
     * 机构导出数据
     *
     * @param ao     请求参数
     * @param stream 输出流
     */
    @Override
    public void exportOrg(OrgPageAO ao, ServletOutputStream stream) {
        ao.setSize(-1);
        List<OrgVO> vos = queryOrgPage(ao).getRecords();
        List<OrgExcelVO> list = new ArrayList<>(vos.size());
        for (OrgVO vo : vos) {
            OrgExcelVO excelVo = new OrgExcelVO();
            BeanUtils.copyProperties(vo, excelVo);
            list.add(excelVo);
        }

        ExcelWriter excelWriter = EasyExcelFactory.write(stream).build();
        excelWriter.write(list, EasyExcelFactory.writerSheet(NumberConstants.ZERO).head(OrgExcelVO.class).build());
        excelWriter.finish();
    }

    /**
     * 机构启用、停用
     *
     * @param ao 请求参数
     */
    @Override
    public void enableOrg(OrgEnabledAO ao) {
        this.lambdaUpdate().eq(Org::getId, ao.getId()).set(Org::getEnabled, ao.getEnabled()).update(new Org());
    }

    /**
     * 机构下拉列表查询
     *
     * @param ao 请求参数
     * @return List<OrgDropDownVO> 响应参数
     */
    @Override
    public List<OrgDropDownVO> queryOrgDropDown(OrgDropDownAO ao) {
        return baseMapper.queryOrgDropDown(ao);
    }
}